package cn.fsd.service.impl;

import cn.fsd.domain.Purchase_bill;
import cn.fsd.domain.Storeroom;
import cn.fsd.domain.Storeroom_commodity;
import cn.fsd.mapper.CommodityMapper;
import cn.fsd.mapper.StoreroomMapper;
import cn.fsd.mapper.Storeroom_commodityMapper;
import cn.fsd.query.delivery.StoreroomCommodityQuery;
import cn.fsd.service.StoreRoomCommodityService;
import cn.fsd.vo.CommodityBean;
import cn.fsd.vo.PageBean;
import cn.fsd.vo.StoreRoomCommodityBean;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class StoreRoomCommodityServiceImpl implements StoreRoomCommodityService {

  @Autowired
  Storeroom_commodityMapper storeroomCommodityMapper;
  /**
   * 此处commodity微服务接口待完善
   */
  @Autowired
  CommodityMapper commodityMapper;
  @Autowired
  StoreroomMapper storeroomMapper;
  /**
   * 微服务搭建后调用接口即可
   */
  @Autowired
  CommodityServiceImpl commodityService;

  @Override
  public PageBean<Storeroom_commodity> getCommodityByPage(StoreroomCommodityQuery query) {
    PageBean<Storeroom_commodity> pageBean = new PageBean<>();

    PageHelper.startPage(query.getPageNow(), query.getPageSize());

    List<Storeroom_commodity> result = storeroomCommodityMapper.findCommodityByPage(query);

    PageInfo<Storeroom_commodity> pageInfo = new PageInfo<>(result);

    pageInfo.setList(pageInfo.getList().parallelStream().map(item -> {
      // TODO 此处之后需要替换成使用openfeign调用deliveryService的commodity相关接口
      CommodityBean commodity = commodityService.findCommodityById(item.getCommodity_id());
      StoreRoomCommodityBean bean = new StoreRoomCommodityBean(item);
      if (commodity != null) {
        bean.setCommodityName(commodity.getCommodity_name());
        bean.setCommodityCode(commodity.getCommodity_code());
      } else {
        bean.setCommodityName("未知商品");
        bean.setCommodityCode("------");
      }
      return bean;
    }).collect(Collectors.toList()));

    pageBean.setTotalPages(pageInfo.getPages());
    pageBean.setTotalRows(pageInfo.getTotal());
    pageBean.setRowData(pageInfo.getList());

    return pageBean;
  }

  @Override
  public int updateStoreValues(Storeroom_commodity storeroomCommodity) {
    Storeroom_commodity commodity = storeroomCommodityMapper.selectByPrimaryKey(
        storeroomCommodity.getCommodity_id(), storeroomCommodity.getStoreroom_id());
    if (commodity == null) {
      return -1;
    } else if (storeroomCommodity.getMax_num() < calStockNum(commodity)) {
      return -2;
    }
    storeroomCommodityMapper.updateMaxLowValues(storeroomCommodity);
    return 1;
  }

  @Override
  public PageBean<Storeroom_commodity> queryInventory(StoreroomCommodityQuery query) {
    PageBean<Storeroom_commodity> pageBean = new PageBean<>();

    List<String> ids = commodityMapper.getCommodityIDsByName(query.getQuery());

    PageHelper.startPage(query.getPageNow(), query.getPageSize());

    List<Storeroom_commodity> result = storeroomCommodityMapper.getStoreroomInventoryByPage(query,
        ids);

    PageInfo<Storeroom_commodity> pageInfo = new PageInfo<>(result);

    pageInfo.setList(pageInfo.getList().parallelStream().map(item -> {
      CommodityBean commodity = commodityService.findCommodityById(item.getCommodity_id());
      Storeroom storeroom = storeroomMapper.selectByPrimaryKey(item.getStoreroom_id());
      StoreRoomCommodityBean bean = new StoreRoomCommodityBean(item);
      if (commodity != null) {
        bean.setCommodityName(commodity.getCommodity_name());
        bean.setCommodityCode(commodity.getCommodity_code());
      } else {
        bean.setCommodityName("未知商品");
        bean.setCommodityCode("------");
      }
      if (storeroom != null) {
        bean.setStoreroomName(storeroom.getStoreroom_name());
      } else {
        bean.setStoreroomName("未知库房");
      }
      return bean;
    }).collect(Collectors.toList()));

    pageBean.setRowData(pageInfo.getList());
    pageBean.setTotalRows(pageInfo.getTotal());
    pageBean.setTotalPages(pageInfo.getPages());

    return pageBean;
  }

  @Override
  public PageBean<Storeroom_commodity> queryOutOfStock(StoreroomCommodityQuery query) {

    PageBean<Storeroom_commodity> pageBean = new PageBean<>();

    // TODO 此处也需要修改为调用commodity的接口实现 返回根据名称模糊查询出来的商品id列表
    List<String> ids = commodityMapper.getCommodityIDsByName(query.getQuery());

    PageHelper.startPage(query.getPageNow(), query.getPageSize());

    List<Storeroom_commodity> result = storeroomCommodityMapper.queryOutOfStock(query, ids);

    PageInfo<Storeroom_commodity> pageInfo = new PageInfo<>(result);

    pageInfo.setList(pageInfo.getList().parallelStream().map(item -> {
      // TODO 此处之后需要替换成使用openfeign调用deliveryService的commodity相关接口返回commodity信息的封装
      CommodityBean commodity = commodityService.findCommodityById(item.getCommodity_id());
      StoreRoomCommodityBean bean = new StoreRoomCommodityBean(item);
      if (commodity != null) {
        bean.setCommodityName(commodity.getCommodity_name());
        bean.setCommodityCode(commodity.getCommodity_code());
        bean.setMeasureUnit(commodity.getMeasure_unit());
        bean.setFirstClassName(commodity.getFirstClassName());
        bean.setSecondClassName(commodity.getSecondClassName());
        bean.setSupplierId(commodity.getSupplier());
        bean.setSupplierName(commodity.getSupplierName());
      } else {
        bean.setCommodityName("未知商品");
        bean.setCommodityCode("------");
        bean.setMeasureUnit("");
        bean.setFirstClassName("");
        bean.setSecondClassName("");
      }
      bean.setDate(new Date());
      bean.setOutOfStock(calOutOfStock(item));
      bean.setMaxPurchaseNum(calMaxPurchase(item));

      return bean;
    }).collect(Collectors.toList()));

    pageBean.setTotalPages(pageInfo.getPages());
    pageBean.setTotalRows(pageInfo.getTotal());
    pageBean.setRowData(pageInfo.getList());

    return pageBean;

  }

  @Override
  public Storeroom_commodity getCommodityById(String commodityId, String warehouseId) {
    // TODO: 2023/7/3 需要调用commodity微服务接口
    CommodityBean commodityBean = commodityService.findCommodityById(commodityId);
    Storeroom_commodity storeroomCommodity = storeroomCommodityMapper.selectByPrimaryKey(
        commodityId,
        warehouseId);
    if (commodityBean == null || storeroomCommodity == null) {
      return null;
    } else {
      StoreRoomCommodityBean bean = new StoreRoomCommodityBean(storeroomCommodity);
      bean.setCommodityName(commodityBean.getCommodity_name());
      bean.setCommodityCode(commodityBean.getCommodity_code());
      bean.setFirstClassName(commodityBean.getFirstClassName());
      bean.setSecondClassName(commodityBean.getSecondClassName());
      bean.setSupplierName(commodityBean.getSupplierName());
      bean.setSupplierId(commodityBean.getSupplier());
      bean.setMeasureUnit(commodityBean.getMeasure_unit());
      bean.setOutOfStock(calOutOfStock(storeroomCommodity));
      bean.setMaxPurchaseNum(calMaxPurchase(storeroomCommodity));
      return bean;
    }
  }

  @Override
  public Integer updatePurchase(StoreroomCommodityQuery query) {
    Storeroom_commodity commodity = storeroomCommodityMapper.selectByPrimaryKey(
        query.getCommodity_id(), query.getWarehouse_id());
    if (calMaxPurchase(commodity) < query.getPurchase_num()) {
      return -1;
    }
    storeroomCommodityMapper.updatePurchase(query);
    return 1;
  }

  /**
   * @param returnNum 和之前退货的差额，scheduled直接加上这个值
   */
  @Override
  public void updatePurchase(Purchase_bill bill, int returnNum) {
    storeroomCommodityMapper.updateReturn(bill.getStoreroom_id(), bill.getCommodity_id(),
        returnNum);
  }

  @Override
  public Storeroom_commodity getCommodity(String storeroomId, String commodityId) {
    return storeroomCommodityMapper.selectByPrimaryKey(commodityId,storeroomId);
  }

  /**
   * 计算当前仓库一共有多少商品，修改仓库库存最大最小值时使用
   *
   * @param commodity 数据库表记录
   * @return 计算出的库存数量
   */
  public Integer calStockNum(Storeroom_commodity commodity) {
    if (commodity == null) {
      return 0;
    }
    return commodity.getExpected_exchange() + commodity.getExchanged_num()
        + commodity.getTransferable_num() + commodity.getTransferred_num()
        + commodity.getScheduled_num();
  }

  /**
   * 缺货量计算规则
   *
   * @param storeroomCommodity 从库房商品表里查询出来的记录
   * @return 缺货量
   */
  public Integer calOutOfStock(Storeroom_commodity storeroomCommodity) {
    if (storeroomCommodity == null) {
      return 0;
    }
    return (storeroomCommodity.getOut_of_stock() + storeroomCommodity.getLow_num())
        - storeroomCommodity.getTransferable_num() - storeroomCommodity.getScheduled_num();
  }

  /**
   * 计算可以进货的最大数量
   *
   * @param storeroomCommodity 库房商品表记录
   * @return 指定库房指定商品可以进货的最大数量
   */
  public Integer calMaxPurchase(Storeroom_commodity storeroomCommodity) {
    if (storeroomCommodity == null) {
      return 0;
    }
    return storeroomCommodity.getMax_num() - storeroomCommodity.getTransferable_num()
        - storeroomCommodity.getTransferred_num() - storeroomCommodity.getScheduled_num()
        - storeroomCommodity.getExchanged_num() - storeroomCommodity.getExpected_exchange();
  }
}
